/*
 * CCVisu is a tool for visual graph clustering
 * and general force-directed graph layout.
 * This file is part of CCVisu.
 *
 * Copyright (C) 2005-2012  Dirk Beyer
 *
 * CCVisu is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * CCVisu is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with CCVisu; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Please find the GNU Lesser General Public License in file
 * license_lgpl.txt or http://www.gnu.org/licenses/lgpl.txt
 *
 * Dirk Beyer    (firstname.lastname@uni-passau.de)
 * University of Passau, Bavaria, Germany
 */
package org.sosy_lab.ccvisu.ui.controlpanel;

import java.awt.BorderLayout;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.EventObject;

import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JSpinner.NumberEditor;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

import org.sosy_lab.ccvisu.Options;
import org.sosy_lab.ccvisu.Options.OptionsEnum;
import org.sosy_lab.ccvisu.graph.GraphEdge;
import org.sosy_lab.ccvisu.ui.helper.ColorCellRenderer;
import org.sosy_lab.ccvisu.writers.WriterDataLayoutDISP;
import org.sosy_lab.util.Colors;

public class OptionsPanelVisualization extends ControlPanel {
  private static final long    serialVersionUID          = -3397665367586164045L;

  // generic since Java 7; we require Java 6; see svn r825 for comparison
  @SuppressWarnings("rawtypes")
  private JComboBox            backgroundComboBox        = new JComboBox();

  private JSpinner             fontSizeSpinner           = new JSpinner();
  private JFormattedTextField  minVertexSizeTextField    = new JFormattedTextField();

  private boolean              blockApply                = false;
  private final Options        options;
  private WriterDataLayoutDISP writer;

  public OptionsPanelVisualization(Options options, WriterDataLayoutDISP writer) {
    this.options = options;
    this.writer = writer;

    initComponents();
    loadOptions();
  }

  private void initComponents() {
    JPanel paramsPanel = new JPanel();

    minVertexSizeTextField.setText("2.0");
    fontSizeSpinner.setEditor(new NumberEditor(fontSizeSpinner, ""));

    fillBackgroundColorComboBox();

    paramsPanel.setLayout(new GridBagLayout());
    addOptionControls(paramsPanel, "Minimum vertex size:", minVertexSizeTextField);
    addOptionControls(paramsPanel, "Font size:", fontSizeSpinner);
    addOptionControls(paramsPanel, "Background color:", backgroundComboBox);

    setLayout(new BorderLayout());
    add(paramsPanel, BorderLayout.CENTER);

    ActionListener applyOnAction = new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent pE) {
        applyOptions();
      }
    };

    ChangeListener applyOnChange = new ChangeListener() {
      @Override
      public void stateChanged(ChangeEvent pE) {
        applyOptions();
      }
    };

    DocumentListener applyOnDocChange = new DocumentListener() {
      @Override
      public void removeUpdate(DocumentEvent pE) {
        applyOptions();
      }

      @Override
      public void insertUpdate(DocumentEvent pE) {
        applyOptions();
      }

      @Override
      public void changedUpdate(DocumentEvent pE) {
        applyOptions();
      }
    };

    minVertexSizeTextField.getDocument().addDocumentListener(applyOnDocChange);
    fontSizeSpinner.addChangeListener(applyOnChange);
    backgroundComboBox.addActionListener(applyOnAction);
  }

  //JComboBox is generic since Java 7; we require Java 6
  // This method was extracted to suppress the warnings only for these lines of
  // code.  See svn r825 for comparison.
  @SuppressWarnings("unchecked")
  private void fillBackgroundColorComboBox() {
    backgroundComboBox.setRenderer(new ColorCellRenderer());
    backgroundComboBox.addItem(Colors.BLACK);
    backgroundComboBox.addItem(Colors.GRAY);
    backgroundComboBox.addItem(Colors.LIGHTGRAY);
    backgroundComboBox.addItem(Colors.WHITE);
  }

  @Override
  public void applyOptions() {
    if (blockApply) {
      return;
    }

    options.getOption(OptionsEnum.minVert).set((Float) minVertexSizeTextField.getValue());
    options.getOption(OptionsEnum.fontSize).set(Integer.parseInt(fontSizeSpinner.getValue().toString()));
    options.backColor = (Colors) backgroundComboBox.getSelectedItem();

    for (GraphEdge edge : options.graph.getEdges()) {
      if (edge.getSource().isShowVertex() && edge.getTarget().isShowVertex()) {
        edge.setShowEdge(options.getOption(OptionsEnum.showEdges).getBool());
      }
    }

    writer.adjustFrontColor();
    options.graph.notifyAboutLayoutChange(new EventObject(this));
  }

  @Override
  public void loadOptions() {
    blockApply = true;
    try
    {
      minVertexSizeTextField.setValue(options.getOption(OptionsEnum.minVert).getFloat());
      fontSizeSpinner.setValue(options.getOption(OptionsEnum.fontSize).getInt());
      backgroundComboBox.setSelectedItem(options.backColor);

    } finally {
      blockApply = false;
    }
  }
}
